//
//  FECCView.m
//  FECCView
//
//  Created by 杨旭东 on 2017/9/8.
//  Copyright © 2017年 JackYang. All rights reserved.
//

#import "XYFECCView.h"

@interface XYFECCView () <UIGestureRecognizerDelegate>
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *rockerResponseCenterX;

@property (weak, nonatomic) IBOutlet UIView *rockerResponseView;

@property (nonatomic, strong) XYRockerView *rockerBackView;

@property (nonatomic, strong) XYRockerView *robotRockerview;

@property (nonatomic, strong) CAGradientLayer *gradientLayer;

@property (nonatomic, strong) CAGradientLayer *robotGradientLayer;

@property (nonatomic, copy) void (^InuseBlock)(BOOL);

@property (nonatomic, copy) void (^ResultBlock)(XYRockerDirection, BOOL);

@property (weak, nonatomic) IBOutlet UIButton *zoomInBtn;

@property (weak, nonatomic) IBOutlet UIButton *zoomOutBtn;

@property (weak, nonatomic) IBOutlet UIView *pedestalRockerResponseView;

@property (weak, nonatomic) IBOutlet UIButton *robotTurnLeftBtn;

@property (weak, nonatomic) IBOutlet UIButton *robotTurnRightBtn;

@end

@implementation XYFECCView

+ (XYFECCView *(^)())addFECCView{
    return ^(){
        XYFECCView *fecc = [[NSBundle mainBundle] loadNibNamed:@"XYFECCView" owner:nil options:nil].firstObject;
        return fecc;
    };
}

- (void)awakeFromNib{
    [super awakeFromNib];
    
    __weak XYFECCView *weakSelf = self;
    self.frame = CGRectMake([self _isFullScreen]?35:15, ([UIScreen mainScreen].bounds.size.height - 135) * .5f, [UIScreen mainScreen].bounds.size.width - 30, 135);

    CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
    self.rockerBackView = XYRockerView.addXYRocker(CGPointMake((screenWidth - 254 - 30) + 254 * .5f - 65, 135 * .5f - 65), XYRockerViewType_Normal);
    [self addSubview:self.rockerBackView];
    [self.rockerBackView rockerResult:^(XYRockerDirection direction, BOOL step) {
        [weakSelf showHighlight:direction weakSelf:weakSelf];
        weakSelf.ResultBlock(direction, step);
    }];
    
    self.rockerResponseView.layer.masksToBounds = true;
    self.pedestalRockerResponseView.layer.masksToBounds = true;
    
    CGPoint origin = self.pedestalRockerResponseView.frame.origin;
    self.robotRockerview = XYRockerView.addXYRocker(CGPointMake(origin.x + 2.5, origin.y + 2.5), XYRockerViewType_Robot);
    [self addSubview:self.robotRockerview];
    [self.robotRockerview rockerResult:^(XYRockerDirection direction, BOOL step) {
        [weakSelf showRobotHighlight:direction weakSelf:weakSelf];
        weakSelf.ResultBlock(direction, step);
    }];
}

- (BOOL)_isFullScreen {
#if __clang_major__ > 10
    if (@available(iOS 11.0, *)) {
#else
    if ([UIDevice currentDevice].systemVersion.floatValue >= 11) {
#endif
        CGFloat height = [[UIApplication sharedApplication] delegate].window.safeAreaInsets.bottom;
        return (height > 0);
    } else {
        return NO;
    }
}

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
    id hitView = [super hitTest:point withEvent:event];
    if ([hitView isMemberOfClass:[UIButton class]] || [hitView isMemberOfClass:[XYRockerPointView class]] || [hitView isMemberOfClass:[XYRobotRockerPointView class]]) {
        return hitView;
    } else return nil;
}

- (XYFECCView *(^)(void (^)(BOOL)))inUse{
    return ^(void (^InuseBlock)(BOOL)){
        self.InuseBlock = InuseBlock;
        return self;
    };
}

- (XYFECCView *(^)(void (^)(XYFECCOperation)))operation{
    return ^(void (^OperationBlock)(XYFECCOperation)){
        __weak XYFECCView * weakSelf = self;
        return self.result(^(XYRockerDirection direction, BOOL step){
            XYFECCOperation operation;
            switch (direction) {
                case XYRockerDirection_Up:{
                    weakSelf.InuseBlock(true);
                    operation = step ? XYTILT_CAMERA_STEP_UP : XYTILT_CAMERA_TURN_UP;
                    break;
                }
                    
                case XYRockerDirection_Down:{
                    weakSelf.InuseBlock(true);
                    operation = step ? XYTILT_CAMERA_STEP_DOWN : XYTILT_CAMERA_TURN_DOWN;
                    break;
                }
                    
                case XYRockerDirection_Left:{
                    weakSelf.InuseBlock(true);
                    operation = step ? XYFECCOPeration_StepLeft : XYFECCOperation_TurnLeft;
                    break;
                }
                    
                case XYRockerDirection_Right:{
                    weakSelf.InuseBlock(true);
                    operation = step ? XYFECCOPeration_StepRight : XYFECCOperation_TurnRight;
                    break;
                }
                    
                case XYRockerDirection_ZoomIn:{
                    weakSelf.InuseBlock(true);
                    operation = step ? XYFECCOperation_STEP_ZOOM_IN : XYFECCOperation_ZoomIn;
                    break;
                }
                    
                case XYRockerDirection_ZoomOut:{
                    weakSelf.InuseBlock(true);
                    operation = step ? XYFECCOperation_STEP_ZOOM_OUT : XYFECCOperation_ZoomOut;
                    break;
                }
                    
                case XYRockerDirection_TurnLeft:{
                    weakSelf.InuseBlock(true);
                    operation = step ? XYFECCOperation_MOVE_LEFT_STEP : XYFECCOperation_MOVE_LEFT_TURN;
                    break;
                }
                    
                case XYRockerDirection_TurnRight:{
                    weakSelf.InuseBlock(true);
                    operation = step ? XYFECCOperation_MOVE_RIGHT_STEP : XYFECCOperation_MOVE_RIGHT_TURN;
                    break;
                }
                    
                case XYRockerDirection_Forward:{
                    weakSelf.InuseBlock(true);
                    operation = step ? XYFECCOperation_MOVE_UP_STEP : XYFECCOperation_MOVE_UP_TURN;
                    break;
                }
                    
                case XYRockerDirection_Retreat:{
                    weakSelf.InuseBlock(true);
                    operation = step ? XYFECCOperation_MOVE_DOWN_STEP : XYFECCOperation_MOVE_DOWN_TURN;
                    break;
                }
                    
                default:{
                    if (direction == XYRockerDirection_Reset_Horizontal) {
                        operation = XYFECCOperation_Stop;
                    }else if (direction == XYRockerDirection_Reset_Vertical){
                        operation = XYTILT_CAMERA_TURN_STOP;
                    }else if (direction == XYRockerDirection_Reset_Zoom){
                        operation = XYFECCOperation_ZOOM_TURN_STOP;
                    }else if (direction == XYRockerDirection_Reset_Move){
                        operation = XYFECCOperation_MOVE_STOP;
                    }else{
                        operation = XYFECCOperation_MOVE_STOP;
                    }
                    weakSelf.InuseBlock(false);
                    break;
                }
            }
            
            OperationBlock(operation);
        });
    };
}

- (XYFECCView *(^)(void (^)(XYRockerDirection, BOOL)))result{
    return ^(void (^result)(XYRockerDirection, BOOL)){
        self.ResultBlock = result;
        return self;
    };
}

- (XYFECCView *(^)(BOOL isPortrait))updateFrame {
    return ^(BOOL isPortrait) {
        CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
        CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
        if (isPortrait) {
            //竖屏
            self.frame = CGRectMake(15,screenHeight - 80 - 135, screenWidth - 30, 135);
            self.rockerResponseCenterX.constant = -2.5;
            CGPoint rockerBackViewOrigin = CGPointMake((screenWidth - 135 - 30) * 0.5, 135 * .5f - 65);
            self.rockerBackView.xy_x = rockerBackViewOrigin.x;
            self.rockerBackView.xy_y = rockerBackViewOrigin.y;
            CGPoint robotRockerviewOrigin = CGPointMake(rockerBackViewOrigin.x + 2.5, rockerBackViewOrigin.y + 2.5);
            self.robotRockerview.xy_x = robotRockerviewOrigin.x;
            self.robotRockerview.xy_y = robotRockerviewOrigin.y;
            
        }else{
            //横屏
            CGFloat offsetW = [self _isFullScreen]?50:30;
            self.frame = CGRectMake([self _isFullScreen]?35:15, (screenHeight - 135) * .5f, screenWidth - offsetW, 135);
            
            CGPoint rockerBackViewOrigin = CGPointMake((screenWidth - 254 - offsetW) + 254 * .5f - 65, 135 * .5f - 65);
            self.rockerBackView.xy_x = rockerBackViewOrigin.x;
            self.rockerBackView.xy_y = rockerBackViewOrigin.y;
            self.rockerResponseView.xy_x = rockerBackViewOrigin.x;
            self.rockerResponseView.xy_y  = rockerBackViewOrigin.y;
            
            self.rockerResponseCenterX.constant = (screenWidth - 135 - offsetW) * 0.5 - 60;
            
            CGPoint origin = self.pedestalRockerResponseView.frame.origin;
            CGPoint robotRockerviewOrigin = CGPointMake(origin.x + 2.5, origin.y + 2.5);
            self.robotRockerview.xy_x = robotRockerviewOrigin.x;
            self.robotRockerview.xy_y = robotRockerviewOrigin.y;
        }
        return self;
    };
}

- (XYFECCView *(^)(BOOL))horizontalMode{
    return ^(BOOL horizontal){
        _rockerBackView.trackMode(horizontal?XYRockerTrackType_Horizontal:XYRockerTrackType_Free);
        _zoomInBtn.hidden = YES;
        _zoomOutBtn.hidden = YES;
        return self;
    };
}

- (XYFECCView *(^)())zoomMode{
    return ^(){
        _zoomInBtn.hidden = _zoomOutBtn.hidden = NO;
        _rockerBackView.trackMode(XYRockerTrackType_Free);
        return self;
    };
}

- (void (^)(BOOL))robotMode{
    return ^(BOOL robot){
        self.robotTurnLeftBtn.hidden = !robot;
        self.robotTurnRightBtn.hidden = !robot;
        self.robotRockerview.hidden = !robot;
        self.pedestalRockerResponseView.hidden = !robot;
        
        if (robot) {
            _rockerBackView.trackMode(XYRockerTrackType_Vertical);
        }
    };
}

- (XYFECCView *(^)(unsigned int, BOOL))capability{
    return ^(unsigned int capability, BOOL onHold){
        if ((capability & 1<<5) != 0) {
            self.hidden = onHold;
            self.robotMode(NO);
        }else if ((capability & 1<<4) != 0){
            self.hidden = onHold;
            self.zoomMode();
            self.robotMode(NO);
        }else if ((capability & 1<<2) != 0){
            self.hidden = onHold;
            self.horizontalMode(onHold);
            self.robotMode(NO);
        }else if ((capability & 1<<1) != 0){
            self.hidden = onHold;
            self.horizontalMode(!onHold);
            self.robotMode(NO);
        }else if (capability == 0){
            self.hidden = YES;
            self.robotMode(NO);
        }
        return self;
    };
}

- (IBAction)stepZoomIn:(UIButton *)sender {
    self.ResultBlock(XYRockerDirection_ZoomIn, YES);
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.5f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        self.ResultBlock(XYRockerDirection_Reset_Zoom, NO);
    });
}

- (IBAction)zoomIn:(UILongPressGestureRecognizer *)sender {
    if (sender.state == UIGestureRecognizerStateBegan) {
        self.ResultBlock(XYRockerDirection_ZoomIn, NO);
    }else  if (sender.state == UIGestureRecognizerStateEnded){
        self.ResultBlock(XYRockerDirection_Reset_Zoom, NO);
    }
}

- (IBAction)stepZoomOut:(UIButton *)sender {
    self.ResultBlock(XYRockerDirection_ZoomOut, YES);
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.5f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        self.ResultBlock(XYRockerDirection_Reset_Zoom, NO);
    });
}

- (IBAction)zoomOut:(UILongPressGestureRecognizer *)sender {
    if (sender.state == UIGestureRecognizerStateBegan) {
        self.ResultBlock(XYRockerDirection_ZoomOut, NO);
    }else if (sender.state == UIGestureRecognizerStateEnded){
        self.ResultBlock(XYRockerDirection_Reset_Zoom, NO);
    }
}

- (IBAction)robotTurnLeftStep:(UIButton *)sender {
    self.ResultBlock(XYRockerDirection_TurnLeft, true);
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.5f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        self.ResultBlock(XYRockerDirection_Reset_Move, false);
    });
}

- (IBAction)robotTurnLeft:(UILongPressGestureRecognizer *)sender {
    if (sender.state == UIGestureRecognizerStateBegan) {
        [_robotTurnLeftBtn setImage:[UIImage imageNamed:@"turnLeft_Highlight"] forState:UIControlStateNormal];
        self.ResultBlock(XYRockerDirection_TurnLeft, false);
    }else  if (sender.state == UIGestureRecognizerStateEnded){
        [_robotTurnLeftBtn setImage:[UIImage imageNamed:@"turnLeft"] forState:UIControlStateNormal];
        self.ResultBlock(XYRockerDirection_Reset_Move, false);
    }
}

- (IBAction)robotTurnRightStep:(UIButton *)sender {
    self.ResultBlock(XYRockerDirection_TurnRight, true);
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.5f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        self.ResultBlock(XYRockerDirection_Reset_Move, false);
    });
}

- (IBAction)robotTurnRight:(UILongPressGestureRecognizer *)sender {
    if (sender.state == UIGestureRecognizerStateBegan) {
        [_robotTurnRightBtn setImage:[UIImage imageNamed:@"turnRight_Highlight"] forState:UIControlStateNormal];
        self.ResultBlock(XYRockerDirection_TurnRight, false);
    }else  if (sender.state == UIGestureRecognizerStateEnded){
        [_robotTurnRightBtn setImage:[UIImage imageNamed:@"turnRight"] forState:UIControlStateNormal];
        self.ResultBlock(XYRockerDirection_Reset_Move, false);
    }
}

- (IBAction)robotTurnRightCancel:(UIButton *)sender {
    self.ResultBlock(XYRockerDirection_Reset_Move, false);
}


- (void)showHighlight:(XYRockerDirection)direction weakSelf:(XYFECCView *)weakSelf{
    [weakSelf.gradientLayer removeFromSuperlayer];
    weakSelf.gradientLayer = nil;
    
    switch (direction) {
        case XYRockerDirection_Up:{
            weakSelf.gradientLayer = [CAGradientLayer layer];
            weakSelf.gradientLayer.colors = @[(__bridge id)[UIColor colorWithRed:1.0f green:60.0/255.0 blue:54.0/255.0 alpha:1].CGColor, (__bridge id)[UIColor clearColor].CGColor];
            weakSelf.gradientLayer.locations = @[@.05, @.4];
            weakSelf.gradientLayer.startPoint = CGPointMake(.0, .0);
            weakSelf.gradientLayer.endPoint = CGPointMake(.0, 1.0);
            weakSelf.gradientLayer.frame = weakSelf.rockerResponseView.bounds;
            [self.rockerResponseView.layer addSublayer:weakSelf.gradientLayer];
            
            break;
        }
            
        case XYRockerDirection_Down:{
            weakSelf.gradientLayer = [CAGradientLayer layer];
            weakSelf.gradientLayer.colors = @[(__bridge id)[UIColor clearColor].CGColor, (__bridge id)[UIColor colorWithRed:1.0f green:60.0/255.0 blue:54.0/255.0 alpha:1].CGColor];
            weakSelf.gradientLayer.locations = @[@.6, @.95];
            weakSelf.gradientLayer.startPoint = CGPointMake(.0, .0);
            weakSelf.gradientLayer.endPoint = CGPointMake(.0, 1.0);
            weakSelf.gradientLayer.frame = weakSelf.rockerResponseView.bounds;
            [self.rockerResponseView.layer addSublayer:weakSelf.gradientLayer];
            
            break;
        }
            
        case XYRockerDirection_Left:{
            weakSelf.gradientLayer = [CAGradientLayer layer];
            weakSelf.gradientLayer.colors = @[(__bridge id)[UIColor colorWithRed:1.0f green:60.0/255.0 blue:54.0/255.0 alpha:1].CGColor, (__bridge id)[UIColor clearColor].CGColor];
            weakSelf.gradientLayer.locations = @[@.05, @.4];
            weakSelf.gradientLayer.startPoint = CGPointMake(.0, .0);
            weakSelf.gradientLayer.endPoint = CGPointMake(1.0, .0);
            weakSelf.gradientLayer.frame = weakSelf.rockerResponseView.bounds;
            [self.rockerResponseView.layer addSublayer:weakSelf.gradientLayer];
            
            break;
        }
            
        case XYRockerDirection_Right:{
            weakSelf.gradientLayer = [CAGradientLayer layer];
            weakSelf.gradientLayer.colors = @[(__bridge id)[UIColor clearColor].CGColor, (__bridge id)[UIColor colorWithRed:1.0f green:60.0/255.0 blue:54.0/255.0 alpha:1].CGColor];
            weakSelf.gradientLayer.locations = @[@.6, @.95];
            weakSelf.gradientLayer.startPoint = CGPointMake(.0, .0);
            weakSelf.gradientLayer.endPoint = CGPointMake(1.0, .0);
            weakSelf.gradientLayer.frame = weakSelf.rockerResponseView.bounds;
            [self.rockerResponseView.layer addSublayer:weakSelf.gradientLayer];
            
            break;
        }
            
        default:{
            
            break;
        }
    }
}

- (void)showRobotHighlight:(XYRockerDirection)direction weakSelf:(XYFECCView *)weakSelf{
    [weakSelf.robotGradientLayer removeFromSuperlayer];
    weakSelf.robotGradientLayer = nil;
    
    switch (direction) {
        case XYRockerDirection_Forward:{
            weakSelf.robotGradientLayer = [CAGradientLayer layer];
            weakSelf.robotGradientLayer.colors = @[(__bridge id)[UIColor colorWithRed:40.0/255.0f green:151.0/255.0 blue:255.0/255.0 alpha:1].CGColor, (__bridge id)[UIColor clearColor].CGColor];
            weakSelf.robotGradientLayer.locations = @[@.05, @.4];
            weakSelf.robotGradientLayer.startPoint = CGPointMake(.0, .0);
            weakSelf.robotGradientLayer.endPoint = CGPointMake(.0, 1.0);
            weakSelf.robotGradientLayer.frame = weakSelf.rockerResponseView.bounds;
            [weakSelf.pedestalRockerResponseView.layer addSublayer:weakSelf.robotGradientLayer];
            
            break;
        }
            
        case XYRockerDirection_Retreat:{
            weakSelf.robotGradientLayer = [CAGradientLayer layer];
            weakSelf.robotGradientLayer.colors = @[(__bridge id)[UIColor clearColor].CGColor, (__bridge id)[UIColor colorWithRed:40.0/255.0f green:151.0/255.0 blue:255.0/255.0 alpha:1].CGColor];
            weakSelf.robotGradientLayer.locations = @[@.6, @.95];
            weakSelf.robotGradientLayer.startPoint = CGPointMake(.0, .0);
            weakSelf.robotGradientLayer.endPoint = CGPointMake(.0, 1.0);
            weakSelf.robotGradientLayer.frame = weakSelf.rockerResponseView.bounds;
            [weakSelf.pedestalRockerResponseView.layer addSublayer:weakSelf.robotGradientLayer];
            
            break;
        }
            
        default:{
            
            break;
        }
    }
}

@end
